// MyLoadMenu.cpp

#include "StdAfx.h"

#include "Common/7Zip/PropID.h"

#include "Common/Archive/CompressCall.h"

#include "AboutDialog.h"
#include "App.h"
#include "HelpUtils.h"
#include "Common/Lang/LangUtils.h"
#include "Common/Registry/RegistryUtils.h"

#include "resource.h"

static const UINT kOpenBookmarkMenuID = 730;
static const UINT kSetBookmarkMenuID = 740;

using namespace Common;


extern void OptionsDialog(HWND hwndOwner);

enum
{
	kMenuIndex_File = 0,
	kMenuIndex_Edit,
	kMenuIndex_View,
	kMenuIndex_Bookmarks
};

static const UINT32 kTopMenuLangIDs[] =
{
	0x03000102,
	0x03000103,
	0x03000104,
	0x03000107,
	0x03000105,
	0x03000106
};

static const UINT32 kAddToFavoritesLangID = 0x03000710;
static const UINT32 kToolbarsLangID = 0x03000451;

static const Lang::CIDLangPair kIDLangPairs[] =
{
	// File
	{ IDM_FILE_OPEN, 0x03000210 },
	{ IDM_FILE_OPEN_INSIDE, 0x03000211 },
	{ IDM_FILE_OPEN_OUTSIDE, 0x03000212 },
	{ IDM_FILE_VIEW, 0x03000220 },
	{ IDM_FILE_EDIT, 0x03000221 },
	{ IDM_RENAME, 0x03000230 },
	{ IDM_COPY_TO, 0x03000231 },
	{ IDM_MOVE_TO, 0x03000232 },
	{ IDM_DELETE, 0x03000233 },
	{ IDM_FILE_PROPERTIES, 0x03000240 },
	{ IDM_FILE_COMMENT, 0x03000241 },
	{ IDM_FILE_CRC, 0x03000242 },
	{ IDM_FILE_DIFF, 0x03000243 },
	{ IDM_FILE_SPLIT, 0x03000270 },
	{ IDM_FILE_COMBINE, 0x03000271 },
	{ IDM_CREATE_FOLDER, 0x03000250 },
	{ IDM_CREATE_FILE, 0x03000251 },
	{ IDCLOSE, 0x03000260 },

	// Edit
	{ IDM_EDIT_CUT, 0x03000320 },
	{ IDM_EDIT_COPY, 0x03000321 },
	{ IDM_EDIT_PASTE, 0x03000322 },

	{ IDM_SELECT_ALL, 0x03000330 },
	{ IDM_DESELECT_ALL, 0x03000331 },
	{ IDM_INVERT_SELECTION, 0x03000332 },
	{ IDM_SELECT, 0x03000333 },
	{ IDM_DESELECT, 0x03000334 },
	{ IDM_SELECT_BY_TYPE, 0x03000335 },
	{ IDM_DESELECT_BY_TYPE, 0x03000336 },

	{ IDM_VIEW_LARGE_ICONS, 0x03000410 },
	{ IDM_VIEW_SMALL_ICONS, 0x03000411 },
	{ IDM_VIEW_LIST, 0x03000412 },
	{ IDM_VIEW_DETAILS, 0x03000413 },

	{ IDM_VIEW_ARANGE_BY_NAME, 0x02000204 },
	{ IDM_VIEW_ARANGE_BY_TYPE, 0x02000214 },
	{ IDM_VIEW_ARANGE_BY_DATE, 0x0200020C },
	{ IDM_VIEW_ARANGE_BY_SIZE, 0x02000207 },
	{ IDM_VIEW_ARANGE_NO_SORT, 0x03000420 },

	{ IDM_OPEN_ROOT_FOLDER, 0x03000430 },
	{ IDM_OPEN_PARENT_FOLDER, 0x03000431 },
	{ IDM_FOLDERS_HISTORY, 0x03000432 },

	{ IDM_VIEW_REFRESH, 0x03000440 },

	{ IDM_VIEW_FLAT_VIEW, 0x03000449 },
	{ IDM_VIEW_TWO_PANELS, 0x03000450 },
	{ IDM_VIEW_ARCHIVE_TOOLBAR, 0x03000460 },
	{ IDM_VIEW_STANDARD_TOOLBAR, 0x03000461 },
	{ IDM_VIEW_TOOLBARS_LARGE_BUTTONS, 0x03000462 },
	{ IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT, 0x03000463 },

	{ IDM_OPTIONS, 0x03000510 },
	{ IDM_BENCHMARK, 0x03000511 },

	{ IDM_HELP_CONTENTS, 0x03000610 },
	{ IDM_ABOUT, 0x03000620 }
};


static int FindLangItem(int ControlID)
{
	for (int i = 0; i < sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]); i++)
		if (kIDLangPairs[i].ControlID == ControlID)
		{
			return i;
		}
	return -1;
}

static int GetSortControlID(PROPID propID)
{
	switch(propID)
	{
		case kpidName:
			return IDM_VIEW_ARANGE_BY_NAME;
		case kpidExtension:
			return IDM_VIEW_ARANGE_BY_TYPE;
		case kpidMTime:
			return IDM_VIEW_ARANGE_BY_DATE;
		case kpidSize:
			return IDM_VIEW_ARANGE_BY_SIZE;
		case kpidNoProperty:
			return IDM_VIEW_ARANGE_NO_SORT;
	}
	return -1;
}


static inline UINT Get_fMaskForString()
{
	return MIIM_TYPE;
}
static inline UINT Get_fMaskForFTypeAndString()
{
	return MIIM_TYPE;
}

static void MyChangeMenu(HMENU menuLoc, int level, int menuIndex)
{
	CMenuHandle menu;
	menu.Attach(menuLoc);
	for (int i = 0;; i++)
	{
		CMenuItemString item;
		item.fMask |= MIIM_SUBMENU | MIIM_ID;
		if (!menu.GetMenuItemInfo(i, TRUE, &item))
		{
			break;
		}
		{
			CString newString;
			if (item.hSubMenu)
			{
				UINT32 langID = 0;
				if (level == 1 && menuIndex == kMenuIndex_Bookmarks)
				{
					langID = kAddToFavoritesLangID;
				}
				else
				{
					MyChangeMenu(item.hSubMenu, level + 1, i);
					if (level == 1 && menuIndex == kMenuIndex_View)
					{
						langID = kToolbarsLangID;
					}
					else if (level == 0 && i < sizeof(kTopMenuLangIDs) / sizeof(kTopMenuLangIDs[0]))
					{
						langID = kTopMenuLangIDs[i];
					}
					else
					{
						continue;
					}
				}
				newString = Lang::LangString(langID);
				if (newString.IsEmpty())
				{
					continue;
				}
			}
			else
			{
				int langPos = FindLangItem(item.wID);
				if (langPos < 0)
				{
					continue;
				}
				newString = Lang::LangString(kIDLangPairs[langPos].LangID);
				if (newString.IsEmpty())
				{
					continue;
				}
				CString shorcutString = item.dwTypeData;
				int tabPos = shorcutString.ReverseFind(wchar_t('\t'));
				if (tabPos >= 0)
				{
					newString += shorcutString.Mid(tabPos);
				}
			}
			{
				item.SetValue(newString);
				menu.SetMenuItemInfo(i, TRUE, &item);
			}
		}
	}
}

static CMenu g_FileMenu;


static void CopyMenu(HMENU srcMenuSpec, HMENU destMenuSpec)
{
	CMenuHandle srcMenu;
	srcMenu.Attach(srcMenuSpec);
	CMenuHandle destMenu;
	destMenu.Attach(destMenuSpec);
	int startPos = 0;
	for (int i = 0;; i++)
	{
		CMenuItemString item;
		if (srcMenu.GetMenuItemInfo(i, TRUE, &item))
		{
			if (destMenu.InsertMenuItem(startPos, TRUE, &item))
			{
				startPos++;
			}
		}
		else
		{
			break;
		}
	}
}

void MyLoadMenu()
{
	HMENU baseMenu;

#ifdef UNDER_CE

	HMENU oldMenu = g_App._commandBar.GetMenu(0);
	if (oldMenu)
	{
		::DestroyMenu(oldMenu);
	}
	BOOL b = g_App._commandBar.InsertMenubar(_AtlBaseModule.GetModuleInstance(), IDR_MAINFRAME, 0);
	baseMenu = g_App._commandBar.GetMenu(0);
	if (!g_LangID.IsEmpty())
	{
		MyChangeMenu(baseMenu, 0, 0);
	}
	g_App._commandBar.DrawMenuBar(0);

#else

	baseMenu = g_App.m_CmdBar.GetMenu();
	if (!g_LangID.IsEmpty())
	{
		MyChangeMenu(baseMenu, 0, 0);
	}
	g_App.m_CmdBar.DrawMenuBar();

#endif

	if ((HMENU)g_FileMenu != 0)
	{
		g_FileMenu.DestroyMenu();
	}

	g_FileMenu.CreatePopupMenu();
	//Copy all file menu items
	CopyMenu(::GetSubMenu(baseMenu, 0), g_FileMenu);
}

void OnMenuActivating(HWND /* hWnd */, HMENU hMenu, int position)
{
	HMENU mainMenu =
#ifdef UNDER_CE
		g_App._commandBar.GetMenu(0);
#else
		g_App.m_CmdBar.GetMenu();
#endif
	;
	if (::GetSubMenu(mainMenu, position) != hMenu)
	{
		return;
	}
	if (position == kMenuIndex_File)
	{
		while(::RemoveMenu(hMenu, 0, MF_BYPOSITION));
		g_App.GetFocusedPanel().CreateFileMenu(hMenu);
	}
	else if (position == kMenuIndex_Edit)
	{
		/*
		CMenu menu;
		menu.Attach(hMenu);
		menu.EnableItem(IDM_EDIT_CUT, MF_ENABLED);
		menu.EnableItem(IDM_EDIT_COPY, MF_ENABLED);
		menu.EnableItem(IDM_EDIT_PASTE, IsClipboardFormatAvailableHDROP() ? MF_ENABLED : MF_GRAYED);
		*/
	}
	else if (position == kMenuIndex_View)
	{
		// View;
		CMenuHandle menu;
		menu.Attach(hMenu);
		menu.CheckMenuRadioItem(IDM_VIEW_LARGE_ICONS, IDM_VIEW_DETAILS,
								IDM_VIEW_LARGE_ICONS + g_App.GetListViewMode(), MF_BYCOMMAND);

		menu.CheckMenuRadioItem(IDM_VIEW_ARANGE_BY_NAME, IDM_VIEW_ARANGE_NO_SORT,
								GetSortControlID(g_App.GetSortID()), MF_BYCOMMAND);


		menu.CheckMenuItem(IDM_VIEW_FLAT_VIEW,  MF_BYCOMMAND | (g_App.GetFlatMode() ? MF_CHECKED : MF_UNCHECKED ) );
		menu.CheckMenuItem(IDM_VIEW_ARCHIVE_TOOLBAR,  MF_BYCOMMAND | (g_App.ShowArchiveToolbar ? MF_CHECKED : MF_UNCHECKED ) );
		menu.CheckMenuItem(IDM_VIEW_STANDARD_TOOLBAR,  MF_BYCOMMAND | (g_App.ShowStandardToolbar ? MF_CHECKED : MF_UNCHECKED ) );
		menu.CheckMenuItem(IDM_VIEW_TOOLBARS_LARGE_BUTTONS,  MF_BYCOMMAND | (g_App.LargeButtons ? MF_CHECKED : MF_UNCHECKED ) );
		menu.CheckMenuItem(IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT,  MF_BYCOMMAND | (g_App.ShowButtonsLables ? MF_CHECKED : MF_UNCHECKED ) );

	}
	else if (position == kMenuIndex_Bookmarks)
	{
		CMenuHandle menu;
		menu.Attach(hMenu);

		CMenuHandle subMenu;
		subMenu.Attach(menu.GetSubMenu(0));
		while(subMenu.RemoveMenu(0, MF_BYPOSITION));

		int i;
		for (i = 0; i < 10; i++)
		{
			CString s = Lang::LangString(IDS_BOOKMARK, 0x03000720);
			s += _T(" ");
			TCHAR c = (TCHAR)(_T('0') + i);
			s += c;
			s += _T("\tAlt+Shift+");
			s += c;
			subMenu.AppendMenu(MF_STRING, kSetBookmarkMenuID + i, s);
		}

		while(menu.RemoveMenu(2, MF_BYPOSITION));

		for (i = 0; i < 10; i++)
		{
			CString path = g_App.AppState.FastFolders.GetString(i);
			const int kMaxSize = 100;
			const int kFirstPartSize = kMaxSize / 2;
			if (path.GetLength() > kMaxSize)
			{
				path = path.Left(kFirstPartSize) + CString(_T(" ... ")) +
					   path.Right(kMaxSize - kFirstPartSize);
			}
			CString s = path;
			if (s.IsEmpty())
			{
				s = _T("-");
			}
			s += _T("\tAlt+");
			s += (TCHAR)(_T('0') + i);
			menu.AppendMenu(MF_STRING, kOpenBookmarkMenuID + i, s);
		}
	}
}


void LoadFileMenu(HMENU hMenu, int startPos, bool programMenu,
				  bool isFsFolder, int numItems, bool allAreFiles)
{
	CMenuHandle destMenu;
	destMenu.Attach(hMenu);

	CString diffPath;
	Registry::ReadRegDiff(diffPath);

	int numRealItems = startPos;
	for (int i = 0;; i++)
	{
		CMenuItemString item;

		item.fMask |= MIIM_STATE | MIIM_ID;

		if (!g_FileMenu.GetMenuItemInfo(i, TRUE, &item))
		{
			break;
		}

		{
			if (!programMenu && item.wID == IDCLOSE)
			{
				continue;
			}

			if (item.wID == IDM_FILE_DIFF && diffPath.IsEmpty())
			{
				continue;
			}

			bool isOneFsFile = (isFsFolder && numItems == 1 && allAreFiles);
			bool disable = ((item.wID == IDM_FILE_SPLIT || item.wID == IDM_FILE_COMBINE) && !isOneFsFile);

			if (disable || item.fType == MFT_SEPARATOR)
			{
				continue;
			}
			if (destMenu.InsertMenuItem(startPos, TRUE, &item))
			{
				startPos++;
			}
			if (disable)
			{
				destMenu.EnableMenuItem(startPos - 1, MF_BYPOSITION | MF_GRAYED);
			}

			if (item.fType != MFT_SEPARATOR)
			{
				numRealItems = startPos;
			}
		}
	}
	while (destMenu.RemoveMenu(numRealItems, MF_BYPOSITION));
}

bool ExecuteFileCommand(int id)
{
	if (id >= kPluginMenuStartID)
	{
		g_App.GetFocusedPanel().InvokePluginCommand(id);
		g_App.GetFocusedPanel()._sevenZipContextMenu.Release();
		g_App.GetFocusedPanel()._systemContextMenu.Release();
		return true;
	}

	switch (id)
	{
		// File
		case IDM_FILE_OPEN:
			g_App.OpenItem();
			break;
		case IDM_FILE_OPEN_INSIDE:
			g_App.OpenItemInside();
			break;
		case IDM_FILE_OPEN_OUTSIDE:
			g_App.OpenItemOutside();
			break;
		case IDM_FILE_VIEW:
			break;
		case IDM_FILE_EDIT:
			g_App.EditItem();
			break;
		case IDM_RENAME:
			g_App.Rename();
			break;
		case IDM_COPY_TO:
			g_App.CopyTo();
			break;
		case IDM_MOVE_TO:
			g_App.MoveTo();
			break;
		case IDM_DELETE:
		{
			bool shift = (::GetKeyState(VK_SHIFT) & 0x8000) != 0;
			g_App.Delete(!shift);
			break;
		}
		case IDM_FILE_CRC:
			g_App.CalculateCrc();
			break;
		case IDM_FILE_DIFF:
			g_App.DiffFiles();
			break;
		case IDM_FILE_SPLIT:
			g_App.m_wndPanel.SplitSelectedFiles();
			break;
		case IDM_FILE_COMBINE:
			g_App.m_wndPanel.CombineSelectedFiles();
			break;
		case IDM_FILE_PROPERTIES:
			g_App.Properties();
			break;
		case IDM_FILE_COMMENT:
			g_App.Comment();
			break;

		case IDM_CREATE_FOLDER:
			g_App.CreateFolder();
			break;
		case IDM_CREATE_FILE:
			g_App.CreateFile();
			break;
		default:
			return false;
	}
	return true;
}

bool OnMenuCommand(HWND hWnd, int id)
{
	if (ExecuteFileCommand(id))
	{
		return true;
	}

	switch (id)
	{
		// File
		case IDCLOSE:
			SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd);
			SendMessage (hWnd, WM_CLOSE, 0, 0);
			break;

		// Edit
		case IDM_EDIT_CUT:
			g_App.EditCut();
			break;
		case IDM_EDIT_COPY:
			g_App.EditCopy();
			break;
		case IDM_EDIT_PASTE:
			g_App.EditPaste();
			break;
		case IDM_SELECT_ALL:
			g_App.SelectAll(true);
			g_App.RefreshStatusBar();
			break;
		case IDM_DESELECT_ALL:
			g_App.SelectAll(false);
			g_App.RefreshStatusBar();
			break;
		case IDM_INVERT_SELECTION:
			g_App.InvertSelection();
			g_App.RefreshStatusBar();
			break;
		case IDM_SELECT:
			g_App.SelectSpec(true);
			g_App.RefreshStatusBar();
			break;
		case IDM_DESELECT:
			g_App.SelectSpec(false);
			g_App.RefreshStatusBar();
			break;
		case IDM_SELECT_BY_TYPE:
			g_App.SelectByType(true);
			g_App.RefreshStatusBar();
			break;
		case IDM_DESELECT_BY_TYPE:
			g_App.SelectByType(false);
			g_App.RefreshStatusBar();
			break;

		//View
		case IDM_VIEW_LARGE_ICONS:
		case IDM_VIEW_SMALL_ICONS:
		case IDM_VIEW_LIST:
		case IDM_VIEW_DETAILS:
		{
			g_App.SetListViewMode(id);
			break;
		}
		case IDM_VIEW_ARANGE_BY_NAME:
		{
			g_App.SortItemsWithPropID(kpidName);
			break;
		}
		case IDM_VIEW_ARANGE_BY_TYPE:
		{
			g_App.SortItemsWithPropID(kpidExtension);
			break;
		}
		case IDM_VIEW_ARANGE_BY_DATE:
		{
			g_App.SortItemsWithPropID(kpidMTime);
			break;
		}
		case IDM_VIEW_ARANGE_BY_SIZE:
		{
			g_App.SortItemsWithPropID(kpidSize);
			break;
		}
		case IDM_VIEW_ARANGE_NO_SORT:
		{
			g_App.SortItemsWithPropID(kpidNoProperty);
			break;
		}

		case IDM_OPEN_ROOT_FOLDER:
			g_App.OpenRootFolder();
			break;
		case IDM_OPEN_PARENT_FOLDER:
			g_App.OpenParentFolder();
			break;
		case IDM_FOLDERS_HISTORY:
			g_App.FoldersHistory();
			break;
		case IDM_VIEW_REFRESH:
			g_App.RefreshView();
			break;
		case IDM_VIEW_FLAT_VIEW:
			g_App.ChangeFlatMode();
			break;
		case IDM_VIEW_STANDARD_TOOLBAR:
			g_App.SwitchStandardToolbar();
			break;
		case IDM_VIEW_ARCHIVE_TOOLBAR:
			g_App.SwitchArchiveToolbar();
			break;
		case IDM_VIEW_TOOLBARS_SHOW_BUTTONS_TEXT:
			g_App.SwitchButtonsLables();
			break;
		case IDM_VIEW_TOOLBARS_LARGE_BUTTONS:
			g_App.SwitchLargeButtons();
			break;

		// Tools
		case IDM_OPTIONS:
			OptionsDialog(hWnd);
			break;

		case IDM_BENCHMARK:
		{
			CPanel::CDisableTimerProcessing disableTimerProcessing1(g_App.m_wndPanel);
			Archive::Benchmark();
			break;
		}
		// Help
		case IDM_HELP_CONTENTS:
			ShowHelpWindow(NULL, kFMHelpTopic);
			break;
		case IDM_ABOUT:
		{
			CAboutDialog dialog;
			dialog.Create(hWnd);
			break;
		}
		default:
		{
			if (id >= kOpenBookmarkMenuID && id <= kOpenBookmarkMenuID + 9)
			{
				g_App.OpenBookmark(id - kOpenBookmarkMenuID);
				return true;
			}
			else if (id >= kSetBookmarkMenuID && id <= kSetBookmarkMenuID + 9)
			{
				g_App.SetBookmark(id - kSetBookmarkMenuID);
				return true;
			}
			return false;
		}
	}
	return true;
}
